<?php

namespace Alipay\Common;

use Alipay\AlipayFund\Request\AlipayFundBatchCreateRequest;
use Alipay\Http\Response;
use Exception;

class BuilderBase extends Alipay implements Depot
{
    /**
     * @param Request $request
     * @return Response
     * @throws Exception
     * @author xis
     */
    public function execute(Request $request): Response
    {
        $requestParam = $this->generate($request);

        $requestParam = $this->checkCertModel($requestParam);

        $sign = $this->sign($requestParam);

        $requestParam['sign'] = $sign;

        $method = 'get';

        if ($request instanceof AlipayFundBatchCreateRequest) {
            $method = 'post';
        }

        return $this->request($method, $requestParam, $request->getResponse(), $request->getRequestUrl());
    }


    private function checkCertModel($requestParam)
    {
        if ($this->isCertModel) {
            $requestParam["app_cert_sn"] = $this->certClient->getAppPublicCertSN();
            $requestParam["alipay_root_cert_sn"] = $this->certClient->getAlipayRootCertSN();
        }
        return $requestParam;
    }

    /**
     * @throws Exception
     */
    private function sign(array $param): string
    {
        $encrypt = new Encrypt($this);
        $encrypt->setSignType($this->signType);
        $encrypt->setSignParams($param);
        $encrypt->sign();

        return $encrypt->getSignString();

    }

    /**
     * @param Request $request
     * @return array
     * @author xis
     */
    private function generate(Request $request): array
    {
        $param = [
            'app_id' => $this->appId,
            'method' => $request->getMethod(),
            'format' => $this->format,
            'charset' => $this->charset,
            'sign_type' => $this->signType,
            'sign' => '',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'biz_content' => json_encode($request->generate(), JSON_UNESCAPED_UNICODE)
        ];

        if ($request->getAppAuthToken()) {
            $param['app_auth_token'] = $request->getAppAuthToken();
        }

        if ($this->returnUrl) {
            $param['return_url'] = $this->returnUrl;
        }

        return $param;
    }
}
